package concurrent.completableFuture;

import org.junit.Test;

import java.util.concurrent.*;

/**
 * 创建异步任务
 * 子线程是异步执行的，主线程休眠等待子线程执行完成，子线程执行完成后唤醒主线程，主线程获取任务执行结果后退出。
 *
 * @author LoneRanger
 * @version 1.0
 */
public class FutureTest {

	/**
	 * @throws ExecutionException
	 * @throws InterruptedException
	 */
	@Test
	public void test0() throws ExecutionException, InterruptedException {
		ExecutorService executorService = Executors.newCachedThreadPool();

		Future<Double> cf = executorService.submit(() -> {
			System.out.println(Thread.currentThread() + "开始,time->" + System.currentTimeMillis());
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
			}
			if (true) {
				throw new RuntimeException("test");
			} else {
				System.out.println(Thread.currentThread() + "结束,time->" + System.currentTimeMillis());
				return 1.2;
			}
		});

		System.out.println("main concurrent.thread start,time->" + System.currentTimeMillis());
		//cg.get() 等待子线程执行结束，如果已经完成可以返回结果，如果执行任务异常，则get方法会把异常抛出来
		//get() 方法抛出异常后，主线程会异常终止
		System.out.println("run result->" + cf.get());
		System.out.println("main concurrent.thread exit,time->" + System.currentTimeMillis());

	}

	/**
	 * supplyAsync 表示创建带返回值的异步任务的，相当于ExecutorService submit(Callable<T> task)方法，
	 *
	 * @throws ExecutionException
	 * @throws InterruptedException
	 */
	@Test
	public void test1() throws ExecutionException, InterruptedException {
		// 创建有返回值的异步任务
		CompletableFuture<Double> cf = CompletableFuture.supplyAsync(() -> {
			System.out.println(Thread.currentThread() + " start,time->" + System.currentTimeMillis());
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
			}
			if (false) {
				throw new RuntimeException("test");
			} else {
				System.out.println(Thread.currentThread() + " exit,time->" + System.currentTimeMillis());
				return 1.2;
			}
		});

		System.out.println("main concurrent.thread start,time->" + System.currentTimeMillis());
		//等待子任务执行完成
		System.out.println("run result->" + cf.get());
		System.out.println("main concurrent.thread exit,time->" + System.currentTimeMillis());
	}

	/**
	 * runAsync 表示创建无返回值的异步任务，相当于ExecutorService submit(Runnable task)方法，
	 *
	 * @throws ExecutionException
	 * @throws InterruptedException
	 */
	@Test
	public void test2() throws ExecutionException, InterruptedException {
		// 创建没有返回值的异步任务
		CompletableFuture cf = CompletableFuture.runAsync(() -> {
			System.out.println(Thread.currentThread() + " start,time->" + System.currentTimeMillis());
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
			}
			if (false) {
				throw new RuntimeException("test");
			} else {
				System.out.println(Thread.currentThread() + " exit,time->" + System.currentTimeMillis());
			}
		});


		System.out.println("main concurrent.thread start,time->" + System.currentTimeMillis());
		//等待子任务执行完成
		System.out.println("run result->" + cf.get());
		System.out.println("main concurrent.thread exit,time->" + System.currentTimeMillis());
	}
}
